using System;
using System.Globalization;
using System.IO;
using System.Text;
using System.Web.Mvc;

namespace ABC.Mvc
{
	public class HtmlHelperAdapter
	{
		private readonly HtmlHelper _helper;

		public HtmlHelperAdapter( HtmlHelper helper )
		{
			_helper = helper;
		}

		public ViewDataDictionary ViewData
		{
			get { return _helper.ViewData; }
		}

		public ViewContext ViewContext
		{
			get { return _helper.ViewContext; }
		}

		public string RenderPartial( string partialViewName )
		{
			return RenderPartialInternal( partialViewName, _helper.ViewData, null, ViewEngines.Engines );
		}

		internal string RenderPartialInternal( string partialViewName, ViewDataDictionary viewData, object model, ViewEngineCollection viewEngineCollection )
		{
			if( string.IsNullOrEmpty( partialViewName ) )
				throw new ArgumentException( "", "partialViewName" );

			ViewDataDictionary newViewData;

			if( model == null )
				newViewData = new ViewDataDictionary( viewData ?? ViewData );
			else
				newViewData = viewData == null
					? new ViewDataDictionary( model )
					: new ViewDataDictionary( viewData ) { Model = model };

			var contextWriter = new StringWriter();
			var newViewContext = new ViewContext( ViewContext, ViewContext.View, newViewData, ViewContext.TempData, contextWriter );
			var view = FindPartialView( newViewContext, partialViewName, viewEngineCollection );

			var viewWriter = new StringWriter();
			view.Render( newViewContext, viewWriter );
			return viewWriter.ToString();
		}

		internal static IView FindPartialView( ViewContext viewContext, string partialViewName, ViewEngineCollection viewEngineCollection )
		{
			var result = viewEngineCollection.FindPartialView( viewContext, partialViewName );
			if( result.View != null )
				return result.View;

			var locationsText = new StringBuilder();
			foreach( var location in result.SearchedLocations )
			{
				locationsText.AppendLine();
				locationsText.Append( location );
			}

			throw new InvalidOperationException( string.Format( CultureInfo.CurrentUICulture, "", partialViewName, locationsText ) );
		}
	}
}